#include "abc-server-dispatcher.h"

#include "util/net/http-request.h"
#include "util/logger/logger.h"
#include "util/strutil.h"

#include "abc-static-resource-controller.h"
#include "abc-server-main-page-controller.h"
#include "abc-article-manager-controller.h"
#include "abc-server-tool-controller.h"
#include "abc-resource-not-found-controller.h"


static const char *title() {
    return "AbcServerDispatcher ";
}

static bool isStaticResource(const std::string_view &uri) {
    using strutil::endWith;
    
    if (endWith(uri, ".css")) {
        return true;
    }

    if (endWith(uri, ".js")) {
        return true;
    }

    if (endWith(uri, ".html")) {
        return true;
    }

    if (endWith(uri, ".svg")) {
        return true;
    }

    return false;
}

AbcServerDispatcher::AbcServerDispatcher(AbcServer &server)
    : staticResource_(new AbcStaticResourceController)
    , mainPage_(new AbcServerMainPageController(server))
    , articleManager_(new AbcArticleManagerController(server))
    , tool_(new AbcToolController)
    , resourceNotFound_(new AbcResourceNotFoundController) {

}

AbcServerDispatcher::~AbcServerDispatcher() {
    delete resourceNotFound_;
    resourceNotFound_ = nullptr;

    delete tool_;
    tool_ = nullptr;

    delete articleManager_;
    articleManager_ = nullptr;

    delete mainPage_;
    mainPage_ = nullptr;

    delete staticResource_;
    staticResource_;
}

HttpController *AbcServerDispatcher::dispatch(const HttpRequest &request) {
    if (request.isGet() && request.uri() == "/") {
        return mainPage_;
    }

    if (request.isGet() && request.under(prefix::article::Article)) {
        return articleManager_;
    }

    if (request.isPost() && request.under(prefix::article::ArticleControll)) {
        return articleManager_;
    }

    if (request.isGet() && isStaticResource(request.uri())) {
        return staticResource_;
    }

    if (request.isPost() && request.under(UriPrefix::Tool)) {
        return tool_;
    }

    LOGD << title() << "resource not found by: " << request.logInfo();
    return resourceNotFound_;
}

